﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Duplicate_Checking
{
    class Program
    {
        static void Main(string[] args)
        {

            string orginStr1 = ReadFile(@"C:\Users\念力弯勺\Desktop\001.cpp");
            string orginStr2 = ReadFile(@"C:\Users\念力弯勺\Desktop\002.cpp");
            string dealStr1 = DealString(orginStr1);
            string dealStr2 = DealString(orginStr2);


            int theMinStrNum = Duplicate(dealStr1, dealStr2);
            double repetitionRate = ((double)theMinStrNum) / Math.Max(dealStr1.Length, dealStr2.Length);

            Console.WriteLine("重复率：" + repetitionRate);

            Console.ReadKey();
        }

        /// <summary>
        /// 读文件
        /// </summary>
        public static string ReadFile(string strPath)
        {
            //string strPath = @"C:\Users\念力弯勺\Desktop\001.txt";//文件路径
            StreamReader streamReader = new StreamReader(strPath);//读取文件
            StringBuilder stringBuilder = new StringBuilder();

            //读取流直至文件末尾结束
            while (!streamReader.EndOfStream)
            {
                string strReadLine = streamReader.ReadLine();//读取每行数据

                stringBuilder.Append(strReadLine + '\n');
            }
            //Console.Write(stringBuilder);
            streamReader.Close();
            return stringBuilder.ToString();
        }

        /// <summary>
        /// 处理文本    去除制表符，空格
        /// </summary>
        public static string DealString(string Originstr)
        {
            StringBuilder sb = new StringBuilder();
            char[] charArray = Originstr.ToCharArray();//变为char数组

            bool isIn = true;//是否放进sb
            bool douXie = false; //是否是双斜线注释   如果到下一行就会消失
            bool starXie = false;//是否是星斜线注释   到达“*/”注释消失

            for (int i = 0; i < Originstr.Length; i++)
            {
                //判断头文件不能放进sb
                if (charArray[i] == '#')
                {
                    isIn = false;
                }
                if (charArray[i] == '>')
                {
                    i++;
                    isIn = true;
                }

                //判断“//”注释不能放进sb
                if (charArray[i] == '/' && charArray[i + 1] == '/')
                {
                    i++;
                    isIn = false;
                    douXie = true;
                }
                if (douXie && charArray[i] == '\n')
                {
                    isIn = true;
                    douXie = false;
                }

                //判断“/*”注释不能放进sb
                if (charArray[i] == '/' && charArray[i + 1] == '*' && !douXie)
                {
                    i++;
                    isIn = false;
                    starXie = true;
                }
                if (charArray[i] == '*' && charArray[i + 1] == '/' && !douXie && starXie)
                {
                    i += 2;
                    isIn = true;
                    starXie = false;
                }

                if (charArray[i] == '\n') continue;
                if (isIn)
                {
                    sb.Append(charArray[i]);
                }
            }

            string str = sb.ToString();

            str = str.Trim();//去除字符串前后的空格
            str = str.Replace(" ", "");//去除空格
            str = Regex.Replace(str, @"\t", "");//去除制表符
            str.ToLower();//转成小写

            return str;
        }

        /// <summary>
        /// 对两个string文本查重
        /// </summary>
        /// <param name="str1">文本1</param>
        /// <param name="str2">文本2</param>
        /// <returns>返回最长的公共子序列</returns>
        public static int Duplicate(string str1, string str2)
        {

            int[,] arr = new int[str1.Length + 1, str2.Length + 1];

            for (int i = 0; i < str1.Length + 1; i++)
            {
                for (int j = 0; j < str2.Length + 1; j++)
                {
                    if (i == 0 || j == 0)
                    {
                        arr[i, j] = 0;
                    }
                    else if (str1[i - 1] == str2[j - 1])
                    {
                        arr[i, j] = arr[i - 1, j - 1] + 1;
                    }
                    else
                    {
                        arr[i, j] = Math.Max(arr[i - 1, j], arr[i, j - 1]);
                    }
                }
            }

            return arr[str1.Length, str2.Length];
        }

    }

}
